<?php

/**
 * This file is part of easyCMS.
 *
 * (c) 2023 easyCMS <easyCMS@easycms.net.cn>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace app\middleware;

use app\admin\model\SystemAdmin;
use ReflectionClass;
use ReflectionException;
use Webman\Http\Request;
use Webman\Http\Response;
use Webman\MiddlewareInterface;

class AdminAuth implements MiddlewareInterface
{
    /**
     * @throws ReflectionException
     */
    public function process(Request $request, callable $handler): Response
    {
        $controller = $request->controller;
        $action     = $request->action;
        // 获取控制器鉴权信息
        $class       = new ReflectionClass($controller);
        $properties  = $class->getDefaultProperties();
        $noNeedLogin = $properties['noNeedLogin'] ?? [];
        $noNeedAuth  = $properties['noNeedAuth'] ?? [];

        // 不需要登录
        if (in_array($action, $noNeedLogin, true)) {
            return $handler($request);
        }

        // 获取登录信息
        $admin = \admin();

        if ($admin === null || $admin['id'] < 1) {
            return redirect('/admin/login');
        }

        // 不需要鉴权
        if ($admin['user_type'] === SystemAdmin::SUPER_ADMIN || in_array($action, $noNeedAuth, true)) {
            return $handler($request);
        }

        // 进行鉴权判断，获取permits
        $nameSpace  = substr($controller, 0, strrpos($controller, '\\'));
        $permitsStr = $nameSpace . '\permits';
        $method     = $class->getMethod($action);
        $attributes = $method->getAttributes();
        $permits    = [];

        foreach ($attributes as $attribute) {
            if ($attribute->getName() === $permitsStr) {
                $permits = array_merge($permits, $attribute->getArguments());
            }
        }
        // 没有permits，页面跳转。
        if (count($permits) > 0 && count(array_intersect($permits, $admin['permits'])) < 1) {
            return redirect('/admin/home/noAuth');
        }

        return $handler($request);
    }
}
